Refactoring in Action
step by safe step、かつ、small steps
AだったらN、OだったらBのように文字を入れ替えたい(文字コードをプラマイ13)
リファクタリング前は文字コードで比較する実装
AからMの範囲だったら文字コードに13を足す
文字そのもので比較できる
transformLetter関数には、文字コードの代わりに文字を渡したい
初手 do-nothing statementの追加
transformLetter関数を呼び出す前に、渡したい文字を変数に代入する(だけ)
変数を導入するだけでまだ使わない
テストコードが通っていることを確認
第1引数として追加して、文字を渡す
処理自体は変えていない
transformLetterから呼び出すisBetween関数にもletter引数を追加
ここまでの小ステップで処理の内容には何も手を加えていない
isBetween関数でcharCodeの代わりにletter引数を使うように実装を変更
文字コードを取得する関数が使われなくなったので消せる
cleaning up the code will make more cleanups visible.
「コードをきれいにすると、よりきれいにできる余地が見えるようになる」
追加のクリーンアップをいつやるかは、slack(ゆとり)を考えて決める
ここでやめてもいい
小さくてもコードに示したので一度やめられる
エディタで自動でInline Refactoring
エディタの機能を知って、エディタを使ってリファクタリングする
isBetween関数がなくなる(inlineに展開される)
transformLetter内でcharCodeを取得(引数に再代入した形)
charCode引数を削除
呼び出し元からの削除
正規表現を使った実装に変更
正規表現に当てはまる各文字についてtransformLetter
正規表現を導入した時点では、正規表現は仕事をしておらず、すべての文字を表す正規表現と変わらない
正規表現でa-zA-Zの文字が保証されるので、transformLetterの文字の範囲の判定の式を単純にできる
letter.toUpperCase() <= "M"
テストが落ちたので、まず大文字にする必要があると認識した
if elseに単純化できた
charCodeを変えるのではなく、文字の範囲に応じてrotationを初期化
まず変数rotationを導入するだけ
rotationを使って書き換え(charCodeを変える処理を削除)
エディタの機能でcharCode変数をinlineに
charCode変数が不要になっている
rotation、3項演算子で初期化できる
「もっとコンパクトになるかもしれないが、可読性が犠牲になる」ので、本書ではここで止めた
Breaking a big design change into a sequence of small refactorings
一人だけならできそうだが、チームでどう意志を揃えて進めていくんだろう?
If big design changes are needed, talk them over with your teammates.
TODO: Pythonだとstr.translateを使っても実装できそうな気がする
VSCodeだとRefactorはExtract variable / functionしかサポートされていないかも
Inline variable
Inline function / method
移行的手順の例は、『リファクタリング』の 関数名の変更 にも